package com.example.myapplication.dataBase;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import com.example.myapplication.models.MySubject;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

public class SubjectsDatabaseHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "Subjects.db";
    public static final String subject_TABLE_NAME = "subjects_table";//存储选择的课程
    public static final String subject_TABLE_NAME2 = "all_subjects_table";//所有学期课程

    private static final String COL_1 = "ID";
    private static final String COL_2 = "NAME";
    private static final String COL_3 = "TEACHER";
    private static final String COL_4 = "ROOM";
    private static final String COL_5 = "WEEKLIST";
    private static final String COL_6 = "START";
    private static final String COL_7 = "STEP";
    private static final String COL_8 = "DAY";
    private static final String COL_9 = "TAG";
    private static final String COL_10 = "TERM";

    public SubjectsDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + subject_TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, TEACHER TEXT, ROOM TEXT, WEEKLIST TEXT, START INTEGER, STEP INTEGER, DAY INTEGER, TAG INTEGER, TERM TEXT)");
        db.execSQL("CREATE TABLE " + subject_TABLE_NAME2 + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, TEACHER TEXT, ROOM TEXT, WEEKLIST TEXT, START INTEGER, STEP INTEGER, DAY INTEGER, TAG INTEGER, TERM TEXT)");

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + subject_TABLE_NAME);
        db.execSQL("DROP TABLE IF EXISTS " + subject_TABLE_NAME2);
        onCreate(db);
    }

    public boolean insertData(String name, String teacher, String room, String weeklist, int start, int step, int day, int tag, String term, String tableName) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(COL_2, name);
        contentValues.put(COL_3, teacher);
        contentValues.put(COL_4, room);
        contentValues.put(COL_5, weeklist);
        contentValues.put(COL_6, start);
        contentValues.put(COL_7, step);
        contentValues.put(COL_8, day);
        contentValues.put(COL_9, tag);
        contentValues.put(COL_10, term);
        long result = db.insert(tableName, null, contentValues);
        return result != -1;
    }

    public Cursor getAllData(String tableName) {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.rawQuery("SELECT * FROM " + tableName, null);
    }

    public Cursor getDataById(int id, String tableName) {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.rawQuery("SELECT * FROM " + tableName + " WHERE ID=?", new String[]{String.valueOf(id)});
    }

    public boolean updateData(int id, String name, String teacher, String room, String weeklist, int start, int step, int day, int tag ,int term ,String tableName) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(COL_2, name);
        contentValues.put(COL_3, teacher);
        contentValues.put(COL_4, room);
        contentValues.put(COL_5, weeklist);
        contentValues.put(COL_6, start);
        contentValues.put(COL_7, step);
        contentValues.put(COL_8, day);
        contentValues.put(COL_9, tag);
        contentValues.put(COL_10, term);
        int result = db.update(tableName, contentValues, "ID=?", new String[]{String.valueOf(id)});
        return result > 0;
    }

    public Integer deleteData(int id, String tableName) {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.delete(tableName, "ID=?", new String[]{String.valueOf(id)});
    }


    private Set<Integer> parseWeeklist(String weeklist) {
        Set<Integer> weeks = new HashSet<>();
        String[] parts = weeklist.split(",");
        for (String part : parts) {
            weeks.add(Integer.parseInt(part));
        }
        return weeks;
    }

    private boolean isTimeOverlap(int start1, int step1, int start2, int step2) {
        int end1 = start1 + step1 - 1;
        int end2 = start2 + step2 - 1;
        return start1 <= end2 && start2 <= end1;
    }

//    public int getCursorComponent(Cursor cursor,String str ){
//        return cursor.getInt(cursor.getColumnIndex(str));
//    }

    /**
     * 检测课程上课时间是否冲突 true：冲突 false：不冲突
     * @param tableName
     * @return
     */

    public boolean checkAndMarkConflicts(String tableName) {
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery("SELECT * FROM " + tableName, null);
        if (cursor == null)
            return true;

        boolean hasConflict = false;
        try {
            while (cursor.moveToNext()) {
                int id1 = cursor.getInt(cursor.getColumnIndex(COL_1));
                String weeklist1 = cursor.getString(cursor.getColumnIndex(COL_5));
                int start1 = cursor.getInt(cursor.getColumnIndex(COL_6));
                int step1 = cursor.getInt(cursor.getColumnIndex(COL_7));
                int day1 = cursor.getInt(cursor.getColumnIndex(COL_8));

                Set<Integer> weeks1 = parseWeeklist(weeklist1);

                Cursor cursor2 = db.rawQuery("SELECT * FROM " + tableName + " WHERE " + COL_1 + " != ?", new String[]{String.valueOf(id1)});
                if (cursor2 == null) continue;

                try {

                    while (cursor2.moveToNext()) {
                        int id2 = cursor2.getInt(cursor2.getColumnIndex(COL_1));
                        String weeklist2 = cursor2.getString(cursor2.getColumnIndex(COL_5));
                        int start2 = cursor2.getInt(cursor2.getColumnIndex(COL_6));
                        int step2 = cursor2.getInt(cursor2.getColumnIndex(COL_7));
                        int day2 = cursor2.getInt(cursor2.getColumnIndex(COL_8));

                        if (day1 == day2 && isTimeOverlap(start1, step1, start2, step2)) {
                            Set<Integer> weeks2 = parseWeeklist(weeklist2);
                            for (Integer week : weeks1) {
                                if (weeks2.contains(week)) {
                                    hasConflict = true;
                                    break;
                                }
                            }
                        }

                        if (hasConflict) {
                            ContentValues contentValues = new ContentValues();
                            contentValues.put(COL_9, 1);
                            db.update(tableName, contentValues, "ID=?", new String[]{String.valueOf(id1)});
                            db.update(tableName, contentValues, "ID=?", new String[]{String.valueOf(id2)});
                            break;
                        }
                    }
                } finally {
                    cursor2.close();
                }
            }
        } finally {
            cursor.close();
        }
        return hasConflict;
    }

    public boolean insert_checkAndMarkConflicts(MySubject mySubject,String tableName) {
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery("SELECT * FROM " + tableName, null);
        if (cursor == null)
            return false;
        int id2 = mySubject.getId();
        String weeklist2 = mySubject.getWeekList().stream().map(Objects::toString).collect(Collectors.joining(","));
        int start2 = mySubject.getStart();
        int step2 = mySubject.getStep();
        int day2 = mySubject.getDay();

        boolean hasConflict = false;
        try {
            while (cursor.moveToNext()) {
                int id1 = cursor.getInt(cursor.getColumnIndex(COL_1));
                String weeklist1 = cursor.getString(cursor.getColumnIndex(COL_5));
                int start1 = cursor.getInt(cursor.getColumnIndex(COL_6));
                int step1 = cursor.getInt(cursor.getColumnIndex(COL_7));
                int day1 = cursor.getInt(cursor.getColumnIndex(COL_8));

                Set<Integer> weeks1 = parseWeeklist(weeklist1);

                if (day1 == day2 && isTimeOverlap(start1, step1, start2, step2)) {
                    Set<Integer> weeks2 = parseWeeklist(weeklist2);
                    for (Integer week : weeks1) {
                        if (weeks2.contains(week)) {
                            hasConflict = true;
                            break;
                        }
                    }
                }
            }
        } finally {
            cursor.close();
        }
        return hasConflict;
    }
}
